/**
 ******************************************************************************
 * @file    bl702_sf_ctrl.c
 * @version V1.0
 * @date
 * @brief   This file is the standard driver c file
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of Bouffalo Lab nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */

#include "bl702_sf_ctrl.h"

/** @addtogroup  BL702_Peripheral_Driver
 *  @{
 */

/** @addtogroup  SF_CTRL
 *  @{
 */

/** @defgroup  SF_CTRL_Private_Macros
 *  @{
 */

/*@} end of group SF_CTRL_Private_Macros */

/** @defgroup  SF_CTRL_Private_Types
 *  @{
 */

/*@} end of group SF_CTRL_Private_Types */

/** @defgroup  SF_CTRL_Private_Variables
 *  @{
 */
#define SF_CTRL_BUSY_STATE_TIMEOUT      (5 * 160 * 1000)
#define SF_Ctrl_Get_AES_Region(addr, r) (addr + SF_CTRL_AES_REGION_OFFSET + (r) * 0x100)

/*@} end of group SF_CTRL_Private_Variables */

/** @defgroup  SF_CTRL_Global_Variables
 *  @{
 */

/*@} end of group SF_CTRL_Global_Variables */

/** @defgroup  SF_CTRL_Private_Fun_Declaration
 *  @{
 */

/*@} end of group SF_CTRL_Private_Fun_Declaration */

/** @defgroup  SF_CTRL_Private_Functions
 *  @{
 */

/*@} end of group SF_CTRL_Private_Functions */

/** @defgroup  SF_CTRL_Public_Functions
 *  @{
 */

/****************************************************************************/ /**
                                                                                * @brief  Enable serail flash controller
                                                                                *
                                                                                * @param  cfg: serial flash controller config
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Enable(const SF_Ctrl_Cfg_Type *cfg) {
  uint32_t tmpVal  = 0;
  uint32_t timeOut = 0;

  if (cfg == NULL) {
    return;
  }

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_OWNER_TYPE(cfg->owner));

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      return;
    }
  }

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0);

  if (cfg->clkDelay > 0) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N, cfg->clkDelay - 1);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN);
  }

  /* Serail out inverted, so sf ctrl send on negative edge */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_OUT_INV_SEL, cfg->clkInvert);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_SF_RX_INV_SEL, cfg->rxClkInvert);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal);

  /* Set do di and oe delay */
  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_1);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_0_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_0_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_0_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_1, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_2);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_1_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_1_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_1_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_2, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_3);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_2_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_2_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_2_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_3, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_4);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_3_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_3_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_3_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_4, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_1);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_0_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_0_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_0_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_1, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_2);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_1_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_1_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_1_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_2, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_3);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_2_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_2_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_2_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_3, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_4);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_3_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_3_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_3_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_4, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_1);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_0_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_0_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_0_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_1, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_2);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_1_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_1_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_1_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_2, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_3);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_2_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_2_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_2_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_3, tmpVal);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_4);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_3_DO_DLY_SEL, cfg->doDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_3_DI_DLY_SEL, cfg->diDelay);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_3_OE_DLY_SEL, cfg->oeDelay);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_4, tmpVal);

  /* Enable AHB access sram buffer and enable sf interface */
  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SRAM_EN);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal);

  SF_Ctrl_Set_Owner(cfg->owner);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Enable serail psram controller
                                                                                *
                                                                                * @param  sfCtrlPsramCfg: serial psram controller config
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
// #ifndef BFLB_USE_ROM_DRIVER
//__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Psram_Init(SF_Ctrl_Psram_Cfg *sfCtrlPsramCfg) {
  uint32_t tmpVal = 0;

  SF_Ctrl_Select_Pad(sfCtrlPsramCfg->padSel);
  SF_Ctrl_Select_Bank(sfCtrlPsramCfg->bankSel);

  /* Select psram clock delay */
  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_12);

  if (sfCtrlPsramCfg->psramRxClkInvertSrc) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SRC);

    if (sfCtrlPsramCfg->psramRxClkInvertSel) {
      tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SEL);
    } else {
      tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SEL);
    }
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SRC);
  }

  if (sfCtrlPsramCfg->psramDelaySrc) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_SRC);

    if (sfCtrlPsramCfg->psramClkDelay > 0) {
      tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_EN);
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IF_READ_DLY_N, sfCtrlPsramCfg->psramClkDelay - 1);
    } else {
      tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_EN);
    }
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_SRC);
  }

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_12, tmpVal);

  /* Enable AHB access sram buffer and enable sf interface */
  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SRAM_EN);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal);

  SF_Ctrl_Set_Owner(sfCtrlPsramCfg->owner);
}
// #endif

/****************************************************************************/ /**
                                                                                * @brief  Get flash controller clock delay value
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return Clock delay value
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
uint8_t ATTR_TCM_SECTION SF_Ctrl_Get_Clock_Delay(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0);

  if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN) == 0) {
    return 0;
  } else {
    return BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N) + 1;
  }
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Set flash controller clock delay value
                                                                                *
                                                                                * @param  delay: Clock delay value
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Set_Clock_Delay(uint8_t delay) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0);

  if (delay > 0) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N, delay - 1);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN);
  }

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  SF Ctrl set cmds config
                                                                                *
                                                                                * @param  cmdsCfg: SF Ctrl cmds config
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Cmds_Set(SF_Ctrl_Cmds_Cfg *cmdsCfg) {
  uint32_t tmpVal;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_WRAP_LEN_TYPE(cmdsCfg->wrapLen));

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_3);

  if (cmdsCfg->cmdsEn) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_EN);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_EN);
  }

  if (cmdsCfg->burstToggleEn) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_BT_EN);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_BT_EN);
  }

  if (cmdsCfg->wrapModeEn) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_WRAP_MODE);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_WRAP_MODE);
  }

  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CMDS_WRAP_LEN, cmdsCfg->wrapLen);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_3, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  SF Ctrl pad select
                                                                                *
                                                                                * @param  sel: pad select type
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Select_Pad(SF_Ctrl_Pad_Select sel) {
  /* TODO: sf_if_bk_swap */
  uint32_t tmpVal;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_PAD_SELECT(sel));

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2);

  if (sel <= SF_CTRL_PAD_SEL_SF3) {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, sel);
  } else if (sel >= SF_CTRL_PAD_SEL_DUAL_BANK_SF1_SF2 && sel <= SF_CTRL_PAD_SEL_DUAL_BANK_SF3_SF1) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN);
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_MODE);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, sel - SF_CTRL_PAD_SEL_DUAL_BANK_SF1_SF2);
  } else if (sel == SF_CTRL_PAD_SEL_DUAL_CS_SF2) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN);
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_MODE);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, 1);
  } else if (sel == SF_CTRL_PAD_SEL_DUAL_CS_SF3) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN);
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_MODE);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, 2);
  }

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  SF Ctrl bank select
                                                                                *
                                                                                * @param  sel: bank select type
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Select_Bank(SF_Ctrl_Select sel) {
  /* TODO: sf_if_bk_swap */
  uint32_t tmpVal;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_SELECT(sel));

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2);

  if (sel == SF_CTRL_SEL_FLASH) {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_BK_SEL);
  } else {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_BK_SEL);
  }

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Set flash controller owner:I/D AHB or system AHB
                                                                                *
                                                                                * @param  owner: owner type
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Set_Owner(SF_Ctrl_Owner_Type owner) {
  uint32_t tmpVal  = 0;
  uint32_t timeOut = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_OWNER_TYPE(owner));

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      return;
    }
  }

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);

  /* Set owner */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL, owner);

  /* Set iahb to flash interface */
  if (owner == SF_CTRL_OWNER_IAHB) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_EN);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_EN);
  }

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Disable flash controller
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Disable(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);

  tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Enable flash controller AES with big indian
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Enable_BE(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0);

  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_KEY_ENDIAN);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_IV_ENDIAN);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_DOUT_ENDIAN);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Enable flash controller AES with little indian
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Enable_LE(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0);

  tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_KEY_ENDIAN);
  tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_IV_ENDIAN);
  tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_DOUT_ENDIAN);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Serial flash controller set AES region
                                                                                *
                                                                                * @param  region: region number
                                                                                * @param  enable: enable or not
                                                                                * @param  hwKey: hardware key or software key
                                                                                * @param  startAddr: region start address
                                                                                * @param  endAddr: region end address
                                                                                * @param  locked: lock this region or not
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Region(uint8_t region, uint8_t enable, uint8_t hwKey, uint32_t startAddr, uint32_t endAddr, uint8_t locked) {
  /* Do flash key eco*/
  uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region);
  uint32_t tmpVal;

  if (!hwKey) {
    regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region);
  }

  tmpVal = BL_RD_REG(regionRegBase, SF_CTRL_SF_AES_CFG);

  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_HW_KEY_EN, hwKey);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_START, startAddr / 1024);
  /* sf_aes_end =1 means 1,11,1111,1111 */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_END, endAddr / 1024);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_EN, enable);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_LOCK, locked);

  BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_CFG, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Serial flash controller set AES key
                                                                                *
                                                                                * @param  region: region number
                                                                                * @param  key: key data pointer
                                                                                * @param  keyType: flash controller AES key type:128 bits,192 bits or 256 bits
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) {
  /* Do flash key eco*/
  uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region);
  uint32_t tmpVal, i = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType));

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal);

  if (NULL != key) {
    if (keyType == SF_CTRL_AES_128BITS) {
      i = 4;
      /*
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      */
    } else if (keyType == SF_CTRL_AES_256BITS) {
      i = 8;
      /*
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      */
    } else if (keyType == SF_CTRL_AES_192BITS) {
      i = 6;
      /*
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,__REV(BL_RDWD_FRM_BYTEP(key)));
      key+=4;
      */
    }

    tmpVal = SF_CTRL_SF_AES_KEY_7_OFFSET;

    while (i--) {
      BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(key)));
      key += 4;
      tmpVal -= 4;
    }
  }
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Serial flash controller set AES key with big endian
                                                                                *
                                                                                * @param  region: region number
                                                                                * @param  key: key data pointer
                                                                                * @param  keyType: flash controller AES key type:128 bits,192 bits or 256 bits
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) {
  /* Do flash key eco*/
  uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region);
  uint32_t tmpVal, i = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType));

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal);

  if (NULL != key) {
    if (keyType == SF_CTRL_AES_128BITS) {
      i = 4;
      /*
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      */
    } else if (keyType == SF_CTRL_AES_256BITS) {
      i = 8;
      /*
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      */
    } else if (keyType == SF_CTRL_AES_192BITS) {
      i = 6;
      /*
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,BL_RDWD_FRM_BYTEP(key));
      key+=4;
      BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,BL_RDWD_FRM_BYTEP(key));
      */
    }

    tmpVal = SF_CTRL_SF_AES_KEY_0_OFFSET;

    while (i--) {
      BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(key));
      key += 4;
      tmpVal += 4;
    }
  }
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Serial flash controller set AES iv
                                                                                *
                                                                                * @param  region: region number
                                                                                * @param  iv: iv data pointer
                                                                                * @param  addrOffset: flash address offset
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Set_IV(uint8_t region, uint8_t *iv, uint32_t addrOffset) {
  /* Do flash key eco*/
  uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region);
  uint32_t tmpVal, i = 3;

  if (iv != NULL) {
    tmpVal = SF_CTRL_SF_AES_IV_W3_OFFSET;

    while (i--) {
      BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(iv)));
      iv += 4;
      tmpVal -= 4;
    }

    /*
    BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W3,__REV(BL_RDWD_FRM_BYTEP(iv)));
    iv+=4;
    BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W2,__REV(BL_RDWD_FRM_BYTEP(iv)));
    iv+=4;
    BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W1,__REV(BL_RDWD_FRM_BYTEP(iv)));
    iv+=4;
    */
    BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W0, addrOffset);
    iv += 4;
  }
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Serial flash controller set AES iv with big endian
                                                                                *
                                                                                * @param  region: region number
                                                                                * @param  iv: iv data pointer
                                                                                * @param  addrOffset: flash address offset
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Set_IV_BE(uint8_t region, uint8_t *iv, uint32_t addrOffset) {
  /* Do flash key eco*/
  uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region);
  uint32_t tmpVal, i = 3;

  if (iv != NULL) {
    tmpVal = SF_CTRL_SF_AES_IV_W0_OFFSET;

    while (i--) {
      BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(iv));
      iv += 4;
      tmpVal += 4;
    }

    /*
    BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W0,BL_RDWD_FRM_BYTEP(iv));
    iv+=4;
    BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W1,BL_RDWD_FRM_BYTEP(iv));
    iv+=4;
    BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W2,BL_RDWD_FRM_BYTEP(iv));
    iv+=4;
    */
    BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W3, __REV(addrOffset));
    iv += 4;
  }
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Enable serial flash controller AES
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Enable(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES);
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_EN);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Disable serial flash controller AES
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_AES_Disable(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES);
  tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_EN);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Check is serial flash controller AES enable
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return Wether AES is enable
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
uint8_t ATTR_TCM_SECTION SF_Ctrl_Is_AES_Enable(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES);
  return BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_AES_EN);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Set flash image offset
                                                                                *
                                                                                * @param  addrOffset: Address offset value
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Set_Flash_Image_Offset(uint32_t addrOffset) { BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET, addrOffset); }
#endif

/****************************************************************************/ /**
                                                                                * @brief  Get flash image offset
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return :Address offset value
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
uint32_t ATTR_TCM_SECTION SF_Ctrl_Get_Flash_Image_Offset(void) { return BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET); }
#endif

/****************************************************************************/ /**
                                                                                * @brief  SF controller send one command
                                                                                *
                                                                                * @param  sahbType: Serial flash controller clock sahb sram select
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Select_Clock(SF_Ctrl_Sahb_Type sahbType) {
  uint32_t tmpVal = 0;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0);

  if (sahbType == SF_CTRL_SAHB_CLOCK) {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CLK_SAHB_SRAM_SEL);
  } else if (sahbType == SF_CTRL_FLASH_CLOCK) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CLK_SAHB_SRAM_SEL);
  }

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  SF controller send one command
                                                                                *
                                                                                * @param  cfg: Serial flash controller command configuration pointer
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_SendCmd(SF_Ctrl_Cmd_Cfg_Type *cfg) {
  uint32_t tmpVal  = 0;
  uint32_t timeOut = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode));
  CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode));
  CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode));
  CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode));

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      return;
    }
  }

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);

  if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_SAHB) {
    return;
  }

  /* Clear trigger */
  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0);
  tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_TRIG);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0, tmpVal);

  /* Copy command buffer */
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_1, cfg->cmdBuf[0]);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_2, cfg->cmdBuf[1]);

  /* Configure SPI and IO mode*/
  if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_QPI_MODE_EN, SF_CTRL_SPI_MODE);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_QPI_MODE_EN, SF_CTRL_QPI_MODE);
  }

  if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) {
    if (SF_CTRL_DATA_1_LINE == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_NIO_MODE);
    } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_DO_MODE);
    } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_QO_MODE);
    }
  } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_DIO_MODE);
  } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_QIO_MODE);
  }

  /* Configure cmd */
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_CMD_EN);
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_CMD_BYTE, 0);

  /* Configure address */
  if (cfg->addrSize != 0) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_ADR_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_ADR_BYTE, cfg->addrSize - 1);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_ADR_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_ADR_BYTE, 0);
  }

  /* Configure dummy */
  if (cfg->dummyClks != 0) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DMY_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DMY_BYTE, cfg->dummyClks - 1);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DMY_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DMY_BYTE, 0);
  }

  /* Configure data */
  if (cfg->nbData != 0) {
    tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DAT_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DAT_BYTE, cfg->nbData - 1);
  } else {
    tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DAT_EN);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DAT_BYTE, 0);
  }

  /* Set read write flag */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DAT_RW, cfg->rwFlag);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0, tmpVal);

  // switch sf_clk_sahb_sram_sel = 1
  SF_Ctrl_Select_Clock(SF_CTRL_FLASH_CLOCK);
  /* Trigger */
  tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_TRIG);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0, tmpVal);

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      SF_Ctrl_Select_Clock(SF_CTRL_SAHB_CLOCK);
      return;
    }
  }

  // switch sf_clk_sahb_sram_sel = 0
  SF_Ctrl_Select_Clock(SF_CTRL_SAHB_CLOCK);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Config SF controller for flash I/D cache read
                                                                                *
                                                                                * @param  cfg: Serial flash controller command configuration pointer
                                                                                * @param  cmdValid: command valid or not, for continous read, cache may need no command
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Flash_Read_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) {
  uint32_t tmpVal  = 0;
  uint32_t timeOut = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode));
  CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode));
  CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode));
  CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode));

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      return;
    }
  }

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);

  if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) {
    return;
  }

  /* Copy command buffer */
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_1, cfg->cmdBuf[0]);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_2, cfg->cmdBuf[1]);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_0);

  /* Configure SPI and IO mode*/
  if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_SPI_MODE);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_QPI_MODE);
  }

  if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) {
    if (SF_CTRL_DATA_1_LINE == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_NIO_MODE);
    } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DO_MODE);
    } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QO_MODE);
    }
  } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DIO_MODE);
  } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QIO_MODE);
  }

  if (cmdValid) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0);
  }

  /* Configure address */
  if (cfg->addrSize != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, cfg->addrSize - 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, 0);
  }

  /* configure dummy */
  if (cfg->dummyClks != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, cfg->dummyClks - 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, 0);
  }

  /* Configure data */
  if (cfg->nbData != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 0);
  }

  /* Set read write flag */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_RW, cfg->rwFlag);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_0, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Config psram controller for psram I/D cache write
                                                                                *
                                                                                * @param  cfg: Serial flash controller command configuration pointer
                                                                                * @param  cmdValid: command valid or not, cache may need no command
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Psram_Write_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) {
  uint32_t tmpVal  = 0;
  uint32_t timeOut = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode));
  CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode));
  CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode));
  CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode));

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      return;
    }
  }

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);

  if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) {
    return;
  }

  /* Copy command buffer */
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_4, cfg->cmdBuf[0]);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_5, cfg->cmdBuf[1]);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_3);

  /* Configure SPI and IO mode*/
  if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_QPI_MODE_EN, SF_CTRL_SPI_MODE);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_QPI_MODE_EN, SF_CTRL_QPI_MODE);
  }

  if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) {
    if (SF_CTRL_DATA_1_LINE == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_NIO_MODE);
    } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_DO_MODE);
    } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_QO_MODE);
    }
  } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_DIO_MODE);
  } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_QIO_MODE);
  }

  if (cmdValid) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_BYTE, 0);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_BYTE, 0);
  }

  /* Configure address */
  if (cfg->addrSize != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_BYTE, cfg->addrSize - 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_BYTE, 0);
  }

  /* configure dummy */
  if (cfg->dummyClks != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_BYTE, cfg->dummyClks - 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_BYTE, 0);
  }

  /* Configure data */
  if (cfg->nbData != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DAT_EN, 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DAT_EN, 0);
  }

  /* Set read write flag */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DAT_RW, cfg->rwFlag);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_3, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Config psram controller for psram I/D cache read
                                                                                *
                                                                                * @param  cfg: Serial flash controller command configuration pointer
                                                                                * @param  cmdValid: command valid or not, for continous read, cache may need no command
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
void ATTR_TCM_SECTION SF_Ctrl_Psram_Read_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) {
  uint32_t tmpVal  = 0;
  uint32_t timeOut = 0;

  /* Check the parameters */
  CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode));
  CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode));
  CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode));
  CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode));

  timeOut = SF_CTRL_BUSY_STATE_TIMEOUT;

  while (SET == SF_Ctrl_GetBusyState()) {
    timeOut--;

    if (timeOut == 0) {
      return;
    }
  }

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1);

  if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) {
    return;
  }

  /* Copy command buffer */
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_10, cfg->cmdBuf[0]);
  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_11, cfg->cmdBuf[1]);

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_9);

  /* Configure SPI and IO mode*/
  if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_SPI_MODE);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_QPI_MODE);
  }

  if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) {
    if (SF_CTRL_DATA_1_LINE == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_NIO_MODE);
    } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DO_MODE);
    } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) {
      tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QO_MODE);
    }
  } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DIO_MODE);
  } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QIO_MODE);
  }

  if (cmdValid) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0);
  }

  /* Configure address */
  if (cfg->addrSize != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, cfg->addrSize - 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, 0);
  }

  /* configure dummy */
  if (cfg->dummyClks != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 1);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, cfg->dummyClks - 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 0);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, 0);
  }

  /* Configure data */
  if (cfg->nbData != 0) {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 1);
  } else {
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 0);
  }

  /* Set read write flag */
  tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_RW, cfg->rwFlag);

  BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_9, tmpVal);
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  Get SF Ctrl busy state
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return SET  for SF ctrl busy or RESET for SF ctrl not busy
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_ROM_DRIVER
__WEAK
BL_Sts_Type ATTR_TCM_SECTION SF_Ctrl_GetBusyState(void) {
  uint32_t tmpVal;

  tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0);

  if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_IF_BUSY)) {
    return SET;
  } else {
    return RESET;
  }
}
#endif

/****************************************************************************/ /**
                                                                                * @brief  SF Controller interrupt handler
                                                                                *
                                                                                * @param  None
                                                                                *
                                                                                * @return None
                                                                                *
                                                                                *******************************************************************************/
#ifndef BFLB_USE_HAL_DRIVER
void SF_Ctrl_IRQHandler(void) { /* TODO: Not implemented */ }
#endif

/*@} end of group SF_CTRL_Public_Functions */

/*@} end of group SF_CTRL */

/*@} end of group BL702_Peripheral_Driver */
